class Depend {
    constructor() {
        this.reactiveFns = []
    }

    addDepend(reactiveFn) {
        this.reactiveFns.push(reactiveFn)
    }

    notify() {
        this.reactiveFns.forEach(fn => {
            fn()
        })
    }
}

// 封装一个响应式函数
const depend = new Depend()
function watchFn(fn) {
    depend.addDepend(fn)
}

//封装一个获取depend的函数
const targetMap = new WeakMap() //最外层map对象
//target是当前对象
function getDepend(target, key) {
    //根据target对象获取map的过程
    let map = targetMap.get(target)
    // 如果第一次没有值 就创建一个map
    if (!map) {
        map = new Map()
        targetMap.set(target, map)
    }

    //根据key获取真实的depend对象
    let depend = map.get(key)
    if (!depend) {
        depend = new Depend()
        map.set(key, depend)
      }

      return depend
}

// 对象的响应式
const obj = {
    name: "why", // depend对象
    age: 18 // depend对象
  }

// 监听对象的属性变量: Proxy(vue3)/Object.defineProperty(vue2)
const objProxy = new Proxy(obj, {
    get: function(target, key, receiver) {
      return Reflect.get(target, key, receiver)
    },
    set: function(target, key, newValue, receiver) {
      Reflect.set(target, key, newValue, receiver)
//根据getDepend里面的 传入target和key 获取你当前的depend
      const depend = getDepend(target,key)
      depend.notify()
    }
  })

  watchFn(function() {
    const newName = objProxy.name
    console.log("你好啊, 李银河")
    console.log("Hello World")
    console.log(objProxy.name) // 100行
  })
  
  watchFn(function() {
    console.log(objProxy.name, "demo function -------")
  })
  
  watchFn(function() {
    console.log(objProxy.age, "age 发生变化是需要执行的----1")
  })
  
  watchFn(function() {
    console.log(objProxy.age, "age 发生变化是需要执行的----2")
  })
  
  objProxy.name = "kobe"
objProxy.name = "james"
objProxy.name = "curry"

objProxy.age = 100


const info = {
  name: "kobe",
  address: "广州市"
}

watchFn(function() {
  console.log(info.address, "监听address变化+++++++++1")
})

watchFn(function() {
  console.log(info.address, "监听address变化+++++++++2")
})
  // obj对象
// name: depend
// age: depend

// const objMap = new Map()
// objMap.set("name", "nameDepend")
// objMap.set("age", "ageDepend")

// // info对象
// // address: depend
// // name: depend

// const infoMap = new Map()
// infoMap.set("address", "addressDepend")


// const targetMap = new WeakMap()
// targetMap.set(obj, objMap)
// targetMap.set(info, infoMap)

// // obj.name
// const depend = targetMap.get(obj).get("name")
// depend.notify()
